﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;

// Additional Libraries
using LocalDatabase.Model;
using LocalDatabase.ViewModel;
using System.IO.IsolatedStorage;
using Microsoft.Phone.Notification;
using Microsoft.Phone.Shell;
using System.Security.Cryptography;
using System.Text;
using Microsoft.Phone.Net.NetworkInformation;
using System.Reflection;

namespace FindMe
{
    public partial class Login : PhoneApplicationPage
    {
        IsolatedStorageSettings settings;
        FindMeDataContext db = new FindMeDataContext();
        FindMeFriendServiceReference.FindMeFriendServiceClient serviceClient;
        int _friends = 0;
        int _procesedFriends = 0;
      
        ProgressIndicator progress;
          


        // Constructor
        public Login()
        {
            InitializeComponent();
            settings = IsolatedStorageSettings.ApplicationSettings;
            serviceClient = new FindMeFriendServiceReference.FindMeFriendServiceClient();
            serviceClient.LogInCompleted += new EventHandler<FindMeFriendServiceReference.LogInCompletedEventArgs>(serviceClient_LogInCompleted);

            if (settings.Contains("Username"))
            {
                string username = settings["Username"].ToString();
                txtUsername.Text = username;
            }

            //<-- Progress bar and clock colors -->
            SystemTray.SetIsVisible(this, true);
            SystemTray.SetOpacity(this, 0.0);
            SystemTray.SetBackgroundColor(this, Colors.Black);
            SystemTray.SetForegroundColor(this, Colors.White);
            progress = new ProgressIndicator();
            progress.IsIndeterminate = true;
            progress.Text = "Loading";
            SystemTray.SetProgressIndicator(this, progress);

            //<-- End progress bar and clock colors -->


            if (!DeviceNetworkInformation.IsNetworkAvailable && !DeviceNetworkInformation.IsWiFiEnabled)
            {
                MessageBox.Show("No Cellular or Wi-Fi network is available! Please verify your network connectivity.", "Network Error", MessageBoxButton.OK);
                while (NavigationService.RemoveBackEntry() != null) ;
            }
        }

        // Back OVERRIDE
        protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
        {
            //Sencillo este while elimina todos las posibles backs!!! Luego hace el comando de back tirandote al OS. 
            while (NavigationService.RemoveBackEntry() != null) ;
        }

        void serviceClient_LogInCompleted(object sender, FindMeFriendServiceReference.LogInCompletedEventArgs e)
        {
            Guid sessionToken = e.Result.sessionToken;
            if (sessionToken != new Guid())
            {
                App.FullName = e.Result.name;

                if (settings.Contains("SessionToken"))      // Saving Session Token in Isolated Storage
                {
                    settings["SessionToken"] = sessionToken;
                }
                else
                {
                    settings.Add("SessionToken", sessionToken);
                }

                // Create the database if it does not exist.
                //db = new FindMeDataContext();

                if (!db.DatabaseExists())
                {
                    // Create the local database.
                    db.CreateDatabase();

                    // Save changes to the database.
                    db.SubmitChanges();

                    if (!settings.Contains("Username"))
                    {
                        settings.Add("Username", txtUsername.Text);
                    }
                    else
                    {
                        settings["Username"] = txtUsername.Text;
                    }
                }
                else
                {
                    if (settings.Contains("Username"))
                    {
                        string lastUserName = settings["Username"].ToString();
                        if (lastUserName != txtUsername.Text)
                        {
                            db.FindMeFriends.DeleteAllOnSubmit(db.FindMeFriends);
                            db.SubmitChanges();
                            settings["Username"] = txtUsername.Text;
                        }
                    }
                }

                string channelName = txtUsername.Text + "Channel";
                App.pushChannel = HttpNotificationChannel.Find(channelName);

                if (App.pushChannel == null)
                {
                    if (settings.Contains("PushChannel"))
                    {
                        string lastChannel = settings["PushChannel"].ToString();
                        HttpNotificationChannel pushChannel = HttpNotificationChannel.Find(lastChannel);
                        if (pushChannel != null) { pushChannel.Close(); }
                    }

                    App.pushChannel = new HttpNotificationChannel(channelName);
                    App.pushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(App.pushChannel_ChannelUriUpdated);
                    App.pushChannel.Open();

                    if (!App.pushChannel.IsShellToastBound)
                    {
                        App.pushChannel.BindToShellToast();
                    }

                    if (!App.pushChannel.IsShellTileBound)
                    {
                        App.pushChannel.BindToShellTile();
                    }
                }
                else
                {
                    serviceClient.UpdatePushURIAsync(txtUsername.Text, sessionToken, App.pushChannel.ChannelUri.ToString());
                    App.pushChannel.ChannelUriUpdated += new EventHandler<NotificationChannelUriEventArgs>(App.pushChannel_ChannelUriUpdated);
                }

                if (!settings.Contains("PushChannel"))
                {
                    settings.Add("PushChannel", channelName);
                }
                else
                {
                    settings["PushChannel"] = channelName;
                }

                settings.Save();

                //Microsoft.Phone.UserData.Contacts phoneContacts = new Microsoft.Phone.UserData.Contacts();
                //phoneContacts.SearchCompleted += new EventHandler<Microsoft.Phone.UserData.ContactsSearchEventArgs>(phoneContacts_SearchCompleted);
                //phoneContacts.SearchAsync("", Microsoft.Phone.UserData.FilterKind.None, "FindMe Contact Search");

                progress.IsVisible = false;
                NavigationService.Navigate(new Uri(App.PathMain, UriKind.Relative));
            }
            else
            {
                progress.IsVisible = false;
                MessageBox.Show("LogIn failed! Please check your username and/or password and try again");
                txbForgotPassword.Visibility = System.Windows.Visibility.Visible;
            }
        }

        private void btnLogin_Click(object sender, RoutedEventArgs e)
        {
            progress.IsVisible = true;

            string validUsername = validateUsername();
            string validPassword = validatePassword();

            if (validUsername == "valid" && validPassword == "valid")
            {
                SHA1 sha1 = new SHA1Managed();
                byte[] passwordBytes = Encoding.Unicode.GetBytes(pswPassword.Password);
                byte[] hash = sha1.ComputeHash(passwordBytes);
                string hashedPassword = Encoding.Unicode.GetString(hash, 0, hash.Length);

                try
                {
                    serviceClient.LogInAsync(txtUsername.Text, hashedPassword);
                }
                catch (Exception) { }
            }
            else
            {
               progress.IsVisible = false;
                MessageBox.Show("Username and Password can't be emtpy");
            }
        }

        void phoneContacts_SearchCompleted(object sender, Microsoft.Phone.UserData.ContactsSearchEventArgs e)
        {
            try
            {
                if (e == null) return;
                var contacts = e.Results;
                if (contacts == null) return;

                serviceClient.GetFriendByPhoneOrEmailCompleted += new EventHandler<FindMeFriendServiceReference.GetFriendByPhoneOrEmailCompletedEventArgs>(serviceClient_GetFriendByPhoneOrEmailCompleted);

                foreach (Microsoft.Phone.UserData.Contact c in contacts)
                {
                    if (c == null) continue;

                    char[] phoneTemp;
                    string phoneNumber = "NONE";
                    string email = "NONE";

                    if (c.PhoneNumbers != null)
                    {
                        if (c.PhoneNumbers.Count() > 0)
                        {
                            var mobile = (from mobil in c.PhoneNumbers where mobil.Kind == Microsoft.Phone.UserData.PhoneNumberKind.Mobile select mobil.PhoneNumber);

                            if (mobile.Count() > 0)
                            {
                                phoneNumber = mobile.First();
                                phoneTemp = new char[phoneNumber.Length];

                                int index = 0;
                                foreach (char n in phoneNumber)
                                {
                                    if (n >= '0' && n <= '9')
                                    {
                                        phoneTemp[index++] = n;
                                    }
                                }

                                char[] tmp = new char[index];
                                for (int i = 0; i < index; i++)
                                {
                                    tmp[i] = phoneTemp[i];
                                }
                                phoneNumber = new string(tmp);
                            }
                        }
                    }

                    if (c.EmailAddresses != null)
                    {
                        if (c.EmailAddresses.Count() > 0)
                        {
                            Microsoft.Phone.UserData.ContactEmailAddress mail = c.EmailAddresses.First();
                            email = mail.EmailAddress.Length > 0 ? mail.EmailAddress : "NONE";
                        }
                    }
                    
                    string username = settings["Username"].ToString();
                    Guid sessionToken = (Guid)settings["SessionToken"];

                    try
                    {
                        _friends++;
                        serviceClient.GetFriendByPhoneOrEmailAsync(username, sessionToken, phoneNumber, email);
                    }
                    catch (Exception ex)
                    {
                        MessageBox.Show(ex.Message, "Exception calling serviceClient" , MessageBoxButton.OK);
                    }
                }

                //progress.IsVisible = false;
                //NavigationService.Navigate(new Uri(App.PathMain, UriKind.Relative));
            }
            catch (Exception ex)
            {
                progress.IsVisible = false;
                MessageBox.Show(ex.Message + "\n" + ex.StackTrace, "phoneContacts Exception", MessageBoxButton.OK);
            }
        }

        void serviceClient_GetFriendByPhoneOrEmailCompleted(object sender, FindMeFriendServiceReference.GetFriendByPhoneOrEmailCompletedEventArgs e)
        {
            //try
            //{
                if (e.Result != null)
                {
                    if (!e.Result.isEmpty && db != null)
                    {
                        var friend = e.Result;
                        MessageBox.Show(friend.name);
                        FindMeFriend newFriend = new FindMeFriend()
                        {
                            ContactID = friend.userID,
                            PhoneNumber = friend.phonenumber,
                            UserName = friend.username,
                            Name = friend.name,
                            Email = friend.email,
                            LastLocation = friend.lastLocation
                        };

                        db.FindMeFriends.InsertOnSubmit(newFriend);
                        db.SubmitChanges();
                    }
                    _procesedFriends++;
                }

                if (_procesedFriends == _friends)
                {
                    progress.IsVisible = false;
                    NavigationService.Navigate(new Uri(App.PathMain, UriKind.Relative));
                }
            //}
            //catch (Exception ex)
            //{
            //    MessageBox.Show(ex.Message + "\n" + ex.StackTrace, "serviceClient Exception", MessageBoxButton.OK);
            //}
        }

        private void btnRegister_Click(object sender, RoutedEventArgs e)
        {
            NavigationService.Navigate(new Uri(App.PathRegister, UriKind.Relative));
        }

        string validateUsername()
        {
            string username = txtUsername.Text;

            if (username == string.Empty)
            {
                return "*Username can't be empty";
            }

            return "valid";
        }

        string validatePassword()
        {
            string password = pswPassword.Password;

            if (password == string.Empty)
            {
                return "*Password can't be empty";
            }

            return "valid";
        }

        private void txbForgotPassword_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            NavigationService.Navigate(new Uri(App.PathForgotPass,UriKind.Relative));
        }

        private void LogIn_Click(object sender, EventArgs e)
        {
            progress.IsVisible = true;

            string validUsername = validateUsername();
            string validPassword = validatePassword();

            if (validUsername == "valid" && validPassword == "valid")
            {
                SHA1 sha1 = new SHA1Managed();
                byte[] passwordBytes = Encoding.Unicode.GetBytes(pswPassword.Password);
                byte[] hash = sha1.ComputeHash(passwordBytes);
                string hashedPassword = Encoding.Unicode.GetString(hash, 0, hash.Length);

                try
                {
                    serviceClient.LogInAsync(txtUsername.Text, hashedPassword);
                }
                catch (Exception) { }
            }
            else
            {
                progress.IsVisible = false;
                MessageBox.Show("Username and Password can't be emtpy");
            }
        }

        private void Register_Click(object sender, EventArgs e)
        {
            NavigationService.Navigate(new Uri(App.PathRegister, UriKind.Relative));
        }

        private void txtUsername_MouseEnter(object sender, MouseEventArgs e)
        {
            if (txtUsername.Text == "Username")
            {
                txtUsername.Text = String.Empty;
                txtUsername.Foreground = new SolidColorBrush(Colors.Black);
            }
        }

        private void txtUsername_MouseLeave(object sender, MouseEventArgs e)
        {
            if (txtUsername.Text == String.Empty)
            {
                txtUsername.Foreground = new SolidColorBrush(Colors.Gray);
                txtUsername.Text = "Username";
            }
        }

        private void pswPassword_MouseEnter(object sender, MouseEventArgs e)
        {
            if (pswPassword.Password == string.Empty)
            {
                pswLabel.Text = string.Empty;
            }
        }

        private void pswPassword_MouseLeave(object sender, MouseEventArgs e)
        {
            if (pswPassword.Password == string.Empty)
            {
                pswLabel.Text = "Password";
            }
        }

        private void imgLoginLogo_Tap(object sender, System.Windows.Input.GestureEventArgs e)
        {
            NavigationService.Navigate(new Uri(App.PathMain, UriKind.Relative));
        }

       
    }
}